﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardFactory : MonoBehaviour
{
    // Start is called before the first frame update
    private static CardFactory m_Instance = null;
    public GameObject LittleCardPrototype;
    public GameObject NormalCardPrototype;
    private List<GameObject> LittleCardPool = new List<GameObject>();
    private List<GameObject> NormalCardPool = new List<GameObject>();
    public static CardFactory Instance {
        get {
            if(m_Instance == null) {
                m_Instance = GameObject.FindObjectOfType<CardFactory>() as CardFactory;
            }
            if(!m_Instance) {
                m_Instance = (new GameObject("CardFactory")).AddComponent<CardFactory>();
            }
            return m_Instance;
        }
    }
    [System.Serializable]
    public struct CardProductInfo {
        public GameObject DataPrefab;
        public Sprite LittleSprite;
        public Sprite NormalSprite;
    }
    public List<CardProductInfo> CardProductInfos = new List<CardProductInfo>();
    private Dictionary<CardProps.ID, GameObject> CardPrefabDictionary = new Dictionary<CardProps.ID, GameObject>();
    private Dictionary<CardProps.ID, Sprite> CardLittleSpriteDictionary = new Dictionary<CardProps.ID, Sprite>();
    private Dictionary<CardProps.ID, Sprite> CardNormalSpriteDictionary = new Dictionary<CardProps.ID, Sprite>();
    void Awake() {
        //Debug.Log(CardProductInfos.Count);
        foreach(CardProductInfo info in CardProductInfos) {
            CardProps.ID id = info.DataPrefab.GetComponent<Card>().ID;
            CardPrefabDictionary.Add(id, info.DataPrefab);
            CardLittleSpriteDictionary.Add(id, info.LittleSprite);
            CardNormalSpriteDictionary.Add(id, info.NormalSprite);
        }
    }
    public Card GetDataPrefab(CardProps.ID id) {
        if(CardPrefabDictionary.ContainsKey(id)) {
            return Instantiate(CardPrefabDictionary[id]).GetComponent<Card>();
        }
        else return null;
    }
    
    private GameObject GetLittleCard(CardProps.ID id) {
        Sprite sprite = GetLittleSprite(id);
        if(sprite != null) {
            LittleCardPrototype.SetActive(false);
            GameObject newCard;
            if(NormalCardPool.Count == 0){
                newCard = Instantiate(LittleCardPrototype, new Vector3(0,0,0), Quaternion.identity);
            } else {
                newCard = LittleCardPool[LittleCardPool.Count - 1]; 
                LittleCardPool.RemoveAt(LittleCardPool.Count - 1); 
            }
            InitNewCard(newCard, sprite);
            return newCard;
        }
        return null;
    }
    public GameObject GetNormalCard(CardProps.ID id, int handIndex) {
        Sprite sprite = GetNormalSprite(id);
        if(sprite != null) {
            NormalCardPrototype.SetActive(false);
            GameObject newCard;
            if(true){
                newCard = Instantiate(NormalCardPrototype, new Vector3(0,0,0), Quaternion.identity);
            } else {
                newCard = NormalCardPool[NormalCardPool.Count - 1]; 
                NormalCardPool.RemoveAt(NormalCardPool.Count - 1);
                newCard.transform.position = new Vector3(0,0,0);
                newCard.transform.rotation = Quaternion.identity;
            }
            InitNewCard(newCard, sprite);
            newCard.GetComponent<CardUI>().CurrCardID = id;
            newCard.GetComponent<CardUI>().HandIndex = handIndex;
            return newCard;
        }
        return null;
    }
    public void ReturnNormalCard(GameObject obj) {
        if(obj != null) {
            ResetObj(obj);
            NormalCardPool.Add(obj);
        }
    }
    public void ReturnLittleCard(GameObject obj) {
        if(obj != null) {
            ResetObj(obj);
            LittleCardPool.Add(obj);
        }
    }
    private void ResetObj(GameObject obj) {
        if(obj != null) {
            obj.SetActive(false);
            obj.transform.position = new Vector3(0,0,0);
            obj.transform.rotation = Quaternion.identity;
            if(obj.GetComponent<SpriteRenderer>())
                obj.GetComponent<SpriteRenderer>().sprite = null;
        }
    }
    private void InitNewCard(GameObject obj, Sprite sprite) {
        if(obj.GetComponent<SpriteRenderer>()) {
            obj.GetComponent<SpriteRenderer>().sprite = sprite;
            obj.GetComponent<SpriteRenderer>().color = new Color(1f,1f,1f,1f);
        }
    }
    public Sprite GetLittleSprite(CardProps.ID id) {
        if(CardLittleSpriteDictionary.ContainsKey(id))
            return CardLittleSpriteDictionary[id];
        else return null;
    }
    private Sprite GetNormalSprite(CardProps.ID id) {
        if(CardNormalSpriteDictionary.ContainsKey(id))
            return CardNormalSpriteDictionary[id];
        else return null;
    }
    void Start() {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
